<?php
namespace App\Repositories;

use App\Libs\Log;
use App\Models\Coach;
use App\Models\CoachConfig;
use App\Models\PlanTemplate;
use App\Models\PutPeriod;
use App\Models\SchoolConfig;
use App\Models\Student;
use App\Models\Comment;
use App\Models\StudentCoach;
use App\Models\Subscribe;
use App\Models\CoachLeave;
use Carbon\Carbon;
use function FastRoute\TestFixtures\empty_options_cached;
use function GuzzleHttp\Psr7\str;

class StudytimeRepository extends BaseRepository
{
    public $error = '';
    protected $money = '0.01';
    protected $subscribe;
    public function __construct(
        PutPeriod $putPeriod,
        SubscribesRepository $subscribe
    )
    {
        $this->model = $putPeriod;
        $this->subscribe = $subscribe;
    }

    /**
     * 资源列表
     * @param  array $param 必须传入与模型查询相关的数据
     * @param  string|array $extra 可选额外传入的参数
     * @param  string $size 分页大小（存在默认值）
     * @return Illuminate\Support\Collection
     */
    public function index($param=[], $extra='', $size='10')
    {
        if(!$param['startime'])
            $param['startime'] = strtotime(date('Y-m-d 00:00:00'));//默认为当前时间
        if(!$param['endtime'])
            $param['endtime'] = strtotime(date('Y-m-d 23:59:59'));
        if($param['startime'] < time())
        {
            $param['startime'] = time();
        }
        $student = Student::where('id',$param['student_id'])->first();//学员信息

        //教练资料
        $coach_query = Coach::where('school_id',$student->school_id)->where('employstatus',0);

        //学员驾校是否能查看所有教练权限
        $school_config = SchoolConfig::where('school_id',$student->school_id)->first();

        //不是所有教练则查询绑定教练
        if(!$school_config || !$school_config->all_coach){

            if($param['km']){
                $km[] = $param['km'];
            }else{
                $km = ['2','3'];
            }


            $coach_list = StudentCoach::where('stuid',$student->id)->whereIn('km', $km)->get();

            if($coach_list){
                $coach_ids = [];

                $bind_coach = [];
                foreach($coach_list as $coach){
                    $coach_ids[] = $coach->cid;
                    $bind_coach[$coach->km][] = $coach->cid;//教练绑定科目信息
                }

                $coach_query->whereIn('id',$coach_ids);
            }
        }

        $coachs = $coach_query->select('id as coach_id','name as nickname','photo','teachpermitted','evaluationrate','evaluation as comment','school_id','mobile as userphone')->get()->toArray();

        if(count($coachs) > 0){
            foreach ($coachs as $k=>$coach)
            {

                $param['bind_coach'] = $bind_coach;
                //投放预约查询
                $putimes = $this->coachPeriod($coach, $student, $param);

                if(empty($putimes['list'])){
                    unset($coachs[$k]);
                    continue;
                }

                $coachs[$k]['comment'] = Comment::where('coach_id', $coach['coach_id'])->count();
                $evaluate_perfect = Comment::where('comment', 2)->where('coach_id', $coach['coach_id'])->count();
                $evaluate_good = Comment::where('comment', 1)->where('coach_id',$coach['coach_id'])->count();
                $coachs[$k]['evaluationrate'] =   $coachs[$k]['comment'] ? number_format(($evaluate_good + $evaluate_perfect) /  $coachs[$k]['comment'],2) : 0;

                $coachs[$k]['putime_count'] = $putimes['putime_count'];
                $coachs[$k]['putimes'] = $putimes['list'];

            }
        }
        return array_values($coachs);
    }


    /**
     * 学员获取教练的可预约学时
     * @param $coach
     * @param $student
     * @param $param
     */
    public function coachPeriod($coach, $student, $param)
    {
        //投放预约查询
        $query = $this->model->where('school_id',$coach['school_id'])->where('coach_id',$coach['coach_id'])
            ->where('startime','>=',$param['startime'])
            ->where('student_period', 1)
            ->where('endtime','<=',$param['endtime']);
        if($param['km']){
            $query->where('km',$param['km']);
        }
        if(isset($student->service) && $student->service->subscribetype == 2){ //一车多人 只能看一车多人
            $query->where('max','>',1);
        }

        $putimes = $query->orderBy('startime','asc')->get();

        $putimes_data = [];

        $putimes_data['putime_count'] = 0;
        if(count($putimes) > 0){
            foreach ($putimes as $putime){

                //判断此条预约科目 是否是被绑定到教练
                if(!empty($param['bind_coach'])){
                    if(!isset($param['bind_coach'][$putime->km]) || !in_array($putime->coach_id, $param['bind_coach'][$putime->km])){
                        continue;
                    }
                }

                //判断教练是否已经请假
//                $coach_leave = CoachLeave::where('startime', '<=', "'".date('Y-m-d H:i:s', $putime->startime)."'")
//                                            ->where('endtime', '>=', "'".date('Y-m-d H:i:s', $putime->endtime)."'")
//                                            ->where('isstate', '!=', 2)
//                                            ->where('item_id', $coach['coach_id'])
//                                            ->count();


                $startime = date('Y-m-d H:i:s', $putime->startime);
                $endtime = date('Y-m-d H:i:s', $putime->endtime);
                $coach_leave = CoachLeave::where('item_id',$coach['coach_id'])->where(function($q) use ($startime,$endtime) {
                    $q->whereRaw("`startime` <= '{$startime}' and  `endtime` >= '{$endtime}'");
                })->where('isstate', '!=', 2)->count();


                if($coach_leave){
                    continue;
                }

                if(isset($student->service) && $student->service->paymode == 1){
                    $putime->sum_period = $putime->sum_period;
                    $putime->paymode = 1;
                }else{
                    $putime->paymode = 2;
                }

                $pt["ssms"] = $putime->paymode;
                $pt["km"] = $putime->km;
                $pt["startime"] = $putime->startime;
                $pt["max"] = $putime->max;
                $pt["price"] = $this->subscribe->getPrice($student, $putime);
                $pt["only"] = $putime->only;
                $pt["endtime"] =  $putime->endtime;
                $pt["formula"] = "";
                $pt["id"] = $putime->id;
                $pt["sum_period"] = $putime->sum_period;
                $pt["minute"] = $putime->minute;
                $pt['student_list'] = Subscribe::leftJoin('students', 'students.id', '=', 'yy_subscribes.student_id')
                                                    ->select('students.name','students.photo','students.id')
                                                    ->where('yy_subscribes.status', '!=', '3')
                                                    ->where('yy_subscribes.putime_id', $putime->id)->take(4)->get();

                $putimes_data['putime_count'] += $putime->sum_period / $putime->max * $putime->only;

                $putimes_data['list'][] = $pt;
            }
        }

        return $putimes_data;
    }




    /**
     * 排班计划查询
     * @param  array $param 必须传入与模型查询相关的数据
     * @param  string|array $extra 可选额外传入的参数
     * @return Illuminate\Support\Collection
     */
    public function periodScheduling($param=[], $extra='')
    {
        $param['startime'] = time();
        $param['endtime'] = strtotime(date('Y-m-d 23:59:59',time() + 60*60*24*7));

        $coach =  Coach::where('id',$param['coach_id'])->first();//教练信息
        //投放预约查询
        $query = $this->model->where('school_id',$coach['school_id'])->where('coach_id',$param['coach_id'])
                        ->whereBetween('startime',[$param['startime'],$param['endtime']]);

        $putimes = $query->orderBy('startime','asc')->get();

        $date_list = [];

        for ($i = 0; $i < 7; $i++){
            $date_list[] = date('Y-m-d',strtotime('+ '.$i.' day'));
        }

        $info = [];
        foreach ($date_list as $date){

            $rs['date'] = $date;
            if(count($putimes) > 0){

                $flag = 0;
                foreach ($putimes as $putime){

                    if(date('Y-m-d', $putime->startime) == $date){

                        if($putime->only == 0){
                            $flag = 1;
                            continue;
                        }else{
                            $flag = 0;//如果有一时间段没有满 那么当天就没有满。跳出循环
                            break;
                        }
                    }
                    $flag = 2;//表示无排班
                }

                if ($flag == 1){
                    $rs['status'] = 1;//表示已排满
                }elseif ($flag == 0){
                    $rs['status'] = 2;//表示未排满
                }else{
                    $rs['status'] = 0;//表示无排班
                }
            }else{

                $rs['status'] = 0;//表示无排班
            }
            $info[] = $rs;
        }
        return $info;
    }




    /**
     * 排班计划
     * @param  array $param 必须传入与模型查询相关的数据
     * @param  string|array $extra 可选额外传入的参数
     * @return Illuminate\Support\Collection
     */
    public function crewScheduling($param=[], $extra='')
    {
        $param['startime'] = strtotime($param['times'].' 0:0:0');
        $param['endtime'] = strtotime($param['times'].' 23:59:59');

        $coach =  Coach::where('id',$param['coach_id'])->first();//教练信息
        $student = Student::where('id',$param['student_id'])->first();//学员信息
        //投放预约查询
        $query = $this->model->where('school_id',$coach['school_id'])->where('coach_id',$param['coach_id'])->where('only','>',0)
            ->whereBetween('startime',[$param['startime'],$param['endtime']]);

        $putimes = $query->orderBy('startime','asc')->get();
        if(count($putimes) > 0){
            foreach ($putimes as $putime){
                if($student->service->paymode == 1){
                    $putime->sum_period = $putime->sum_period*$this->money;
                    $putime->paymode = 1;
                }else{
                    $putime->paymode = 2;
                }

                $putime->student_list = Subscribe::leftJoin('students', 'students.id', '=', 'yy_subscribes.student_id')
                    ->select('students.name','students.photo','students.id')
                    ->where('yy_subscribes.status', '!=', '3')
                    ->where('yy_subscribes.putime_id', $putime->id)->take(4)->get();
            }
        }
        return $putimes;
    }


    /**
     * 存储odb
     * @param $inputs
     */
    public function store($inputs, $extra = '')
    {

    }


    /**
     * 更新
     * @param $id
     * @param $input
     * @return mixed
     */
    public function update($id, $input,$extra = '')
    {
        $model = $this->getById($id);
        return $this->save($model,$input);
    }


    /**
     * 编辑特定id资源
     * @param  int $id 资源id
     * @param  string|array $extra 可选额外传入的参数
     * @return Illuminate\Support\Collection
     */
    public function edit($id, $extra)
    {

    }

    /**
     * @param $model
     * @param $inputs
     * @param bool $falg
     * @return mixed
     */
    public function save($model , $inputs , $falg = false)
    {
        return $model;
    }




    /**
     * 教练学时预约信息
     * @param  array $param 必须传入与模型查询相关的数据
     * @param  string|array $extra 可选额外传入的参数
     * @param  string $size 分页大小（存在默认值）
     * @return Illuminate\Support\Collection
     */
    public function coachPeriodList($param=[], $extra='', $size='10')
    {
        if(!$param['startime'])
            $param['startime'] = strtotime(date($param['date'].' 00:00:00'));;//默认为当前时间
        if(!$param['endtime'])
            $param['endtime'] = strtotime(date($param['date'].' 23:59:59'));

        //投放预约查询
        $query = $this->model->where('coach_id',$param['coach_id'])
            ->where('startime','>=',$param['startime'])
            ->where('endtime','<=',$param['endtime']);
        if($param['km']){
            $query->where('km',$param['km']);
        }

        $putimes = $query->orderBy('startime','asc')->get();

        $putimes_data = [];

        if(count($putimes) > 0){
            foreach ($putimes as $putime){

                $pt["km"] = $putime->km;
                $pt["startime"] = $putime->startime;
                $pt["max"] = $putime->max;
                $pt["price"] = '';
                $pt["only"] = $putime->only;
                $pt["endtime"] =  $putime->endtime;
                $pt["formula"] = "";
                $pt["id"] = $putime->id;
                $pt["sum_period"] = $putime->sum_period;
                $pt["minute"] = $putime->minute;
                $pt['student_list'] = Subscribe::leftJoin('students', 'students.id', '=', 'yy_subscribes.student_id')
                    ->select('students.name','students.photo','students.id','students.phone')
                    ->where('yy_subscribes.status', '!=', '3')
                    ->where('yy_subscribes.putime_id', $putime->id)->take(4)->get();

                $putimes_data['list'][] = $pt;
            }
        }
        return $putimes_data;
    }


    public function coachPeriodCount($coach_info, $km = '', $starttime = '', $endtime = '')
    {
        $query_puted = $this->model->where('coach_id', $coach_info->id);
        $query_subscribed = Subscribe::leftJoin('yy_put_periods','yy_subscribes.putime_id','=','yy_put_periods.id')->where('yy_subscribes.coach_id', $coach_info->id);
        if($starttime){
            $query_puted = $query_puted->where('startime', '>=', strtotime($starttime));
            $query_subscribed = $query_subscribed->where('startime', '>=', strtotime($starttime));
        }
        if($endtime){
            $query_puted = $query_puted->where('startime', '<=', strtotime($endtime));
            $query_subscribed = $query_subscribed->where('startime', '<=', strtotime($endtime));
        }
        if($km){
            $query_puted = $query_puted->where('km', $km);
            $query_subscribed = $query_subscribed->where('km', $km);
        }

        $data['puted'] = $query_puted->sum('sum_period');
        $data['subscribed'] = $query_subscribed->where('yy_subscribes.status','!=',3)->sum('study_time');

        return $data;
    }

    /**
     * 教练删除自己的工时
     */
    public function delPeriod($period_id)
    {
        $period_info = $this->model->find($period_id);

        if(!$period_info){
            return ['state' => false, 'msg' => '没有相关工时信息'];
        }

        //当前工时是否有人预约
        $sub = Subscribe::where('status', '!=', 3)->where('putime_id', $period_id)->count();
        if($sub){
            return ['state' => false, 'msg' => '当前工时已经有人预约'];
        }

        $rs = $this->model->where('id', $period_id)->delete();
        if($rs){
            return ['state' => true];
        }

        return ['state' => false, 'msg' => '操作失败'];
    }


    /**
     * 教练投放某天的学时列表
     */
    public function periodPutlist($coach_info, $date)
    {
        $need_insert = false;//是否需要插入单日模板
        //查找单日模板
        $templte_info = PlanTemplate::where('coach_id', $coach_info->id)->where('times', strtotime($date))->orderBy('orders','asc')->get();

        //如果没有单日模板使用个人模板 同时插入单日模板信息
        if(!count($templte_info)){
            $templte_info = PlanTemplate::where('coach_id', $coach_info->id)->where('type', 1)->orderBy('orders','asc')->get();
            $need_insert = true;
        }

        if(!count($templte_info)){
            return ['state' => false, 'msg' => '还没有设置排版模板'];
        }

        $start_time = strtotime($date);
        $end_time = strtotime($date)+24*3600;
        $time_putperiod = PutPeriod::where('coach_id',$coach_info->id)->whereBetween('startime',[$start_time,$end_time])
            ->orderBy('startime')->get();


        if($time_putperiod->count()){
            foreach ($time_putperiod as $vs){

                //排除已经投放冲突的班型计划
                foreach ($templte_info  as $kt=>$vt) {

                    $put_period_info = $this->model->where('coach_id', $coach_info->id)
                        ->where('startime', strtotime($date.' '.$vt['startime']))
                        ->where('endtime', strtotime($date.' '.$vt['endtime']))->first();

                    if($put_period_info){
                        continue;
                    }

                    $mb_startime = strtotime($date.' '.$vt['startime']);
                    $mb_endtime = strtotime($date.' '.$vt['endtime']);
                    $mbtime = ['startime'=>$mb_startime, 'endtime'=>$mb_endtime];
                    if ( self::diffStartimeEndtime($mbtime,$vs) )  {
                        unset($templte_info[$kt]);
                    }
                }
            }
        }

        foreach ($templte_info as $k => $template){
             $put_period_info = $this->model->where('coach_id', $coach_info->id)
                                        ->where('startime', strtotime($date.' '.$template->startime))
                                        ->where('endtime', strtotime($date.' '.$template->endtime))->first();
             $template->is_put = 0;
             $template->subscribed_count = 0;

             if($put_period_info){
                 $template->is_put = 1;
                 $template->subscribed_count = $put_period_info->reserve;
             }

             if($need_insert){
                $temp_data['school_id'] = $template->school_id;
                $temp_data['coach_id'] = $template->coach_id;
                $temp_data['type'] = 2;
                $temp_data['km'] = $template->km;
                $temp_data['startime'] = $template->startime;
                $temp_data['endtime'] = $template->endtime;
                $temp_data['minute'] = $template->minute;
                $temp_data['max'] = $template->max;
                $temp_data['sum_period'] = $template->sum_period;
                $temp_data['times'] = strtotime($date);
                $temp_data['orders'] = $template->orders;
                $temp_data['updated_at'] = $template->updated_at;
                $temp_data['created_at'] = $template->created_at;
                PlanTemplate::insert($temp_data);
            }
        }

        return ['state' => true, 'data' => $templte_info];
    }



    public function diffStartimeEndtime($outarr=[], $inarr=[])
    {
        $jdate=array("startime"=>max($outarr['startime'],$inarr['startime']),"endtime"=>min($outarr['endtime'],$inarr['endtime']));
        if ($jdate['endtime'] > $jdate['startime']) {
            return true;
        }
        return false;
    }

    /**
     * 教练投放学时
     * @param $coach_info
     * @param $data
     */
    public function periodAdd($coach_info, $data)
    {
        $template_data = PlanTemplate::whereIn('id', explode(',', $data['template_id']))->get();

        if(!count($template_data)){
            return ['state' => false, 'msg' => '没有可以投放的学时模板'];
        }

        $coach_config = $coach_info->config;

        $school_coach_config = CoachConfig::where('school_id', $coach_info->school_id)->where('type', 2)->first();

        if($coach_config){//如果教练单独权限
            if(!$coach_config->ch_open_putime){
                return ['state' => false, 'msg' => '没有权限投放工时'];
            }
            $need_pre_days = $coach_config->ch_open_putime_day;
            if(date('Y-m-d', time() + $need_pre_days * 86400) < $data['date']){
                return ['state' => false, 'msg' => '最多投放'.$coach_config->ch_open_putime_day.'天内的工时'];
            }
        }elseif($school_coach_config){//使用驾校统一权限

            if(!$school_coach_config->ch_open_putime){
                return ['state' => false, 'msg' => '没有权限投放工时'];
            }
            $need_pre_days = $school_coach_config->ch_open_putime_day;
            if(date('Y-m-d', time() + $need_pre_days * 86400) < $data['date']){
                return ['state' => false, 'msg' => '最多投放'.$school_coach_config->ch_open_putime_day.'天内的工时'];
            }
        }else{//使用系统默认权限
            if(date('Y-m-d', time() + 3 * 86400) < $data['date']){
                return ['state' => false, 'msg' => '最多投放3天内的工时'];
            }
        }


        $period_data = [];
        $log_str = '';
        foreach($template_data as $template){
            $period['school_id'] = $coach_info->school_id;
            $period['coach_id'] = $coach_info->id;
            $period['km'] = $template->km;
            $period['startime'] = strtotime($data['date'].' '.$template->startime);
            $period['endtime'] = strtotime($data['date'].' '.$template->endtime);
            $period['minute'] = $template->minute;
            $period['max'] = $template->max;
            $period['only'] = $template->max;
            $period['reserve'] = 0;
            $period['student_period'] = $template->student_period;
            $period['sum_period'] = $template->sum_period;
            $period['updated_at'] = date('Y-m-d H:i:s');
            $period['created_at'] = date('Y-m-d H:i:s');
            $startime = $data['date'].' '.$template->startime;
            $endtime = $data['date'].' '.$template->endtime;
            $query = CoachLeave::where('item_id',$coach_info->id)->where('isstate','!=',2);
            $query->where(function($q) use ($startime,$endtime) {
                $q->whereRaw("(`startime` <= '{$startime}' and `endtime` >= '{$startime}') or (`startime` <= '{$endtime}' and `endtime` >= '{$endtime}') or (`startime` >= '{$startime}' and `endtime` <= '{$endtime}')");

            });
            if($query->count()>0)
            {
                return ['state' => false, 'msg' => '此时间段有请假信息,请重新选择投放时间'];
            }
            $period_data[] = $period;
            $log_str .= ' ( '.date('Y-m-d H:i',$period['startime']).'~'.date('Y-m-d H:i',$period['endtime']).' ) ';
        }

        $this->model->insert($period_data);
        $log = Log::get('period_logs');
        $log->addInfo('coach_add:coach_id '.$coach_info->id.' added '.$log_str);
        return ['state' => true];
    }

}